package com.ling.module1sbbyyds.service.video;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ling.sbbyyds.entity.comment.LevenParam;
import com.ling.sbbyyds.entity.users.User;
import com.ling.sbbyyds.entity.video.VideoComment;
import com.ling.sbbyyds.entity.video.VideoCommentLike;
import com.ling.sbbyyds.interaction.vo.commentvo.CommentVo;
import com.ling.sbbyyds.interaction.dto.video.CommentDto;
import com.ling.module1sbbyyds.utils.FileLocalStorageTool;
import com.ling.module1sbbyyds.utils.UserThreadLocal;
import com.ling.sbbyyds.datatools.Base64DecodeMultipartFileUtils;
import com.ling.sbbyyds.imagetools.ImageUtils;
import com.ling.sbbyyds.interaction.ResultVo;
import com.ling.sbbyyds.mapper.user.UserMapper;
import com.ling.sbbyyds.mapper.video.SbbVideoCommentLikeDao;
import com.ling.sbbyyds.mapper.video.SbbVideoCommentMapper;
import com.ling.sbbyyds.mapper.video.VideoMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 天道酬勤、学无止境
 *
 * @Description: 类描述
 * @author: ling
 * @date: 2022年07月23日
 */
@Service
public class SbbVideoCommentService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private FileLocalStorageTool fileLocalStorageTool;
    @Autowired
    private SbbVideoCommentMapper sbbCommentMapper;
    @Autowired
    private SbbVideoCommentLikeDao sbbCommentLikeDao;
    @Autowired
    private VideoMapper videoMapper;

    /**
     * 发布评论
     *
     * @param commentVo 评论内容
     * @return
     * @throws IOException
     */
    public ResultVo publishComment(CommentVo commentVo) throws IOException {
        if(videoMapper.getVideoIsExit(commentVo.getArticleId()) <= 0){
            return ResultVo.fail("视频不存在");
        }

        if (ObjectUtils.isEmpty(commentVo.getContent())) {
            return ResultVo.fail("评论内容不能为空");
        }

        VideoComment comment = new VideoComment();
        BeanUtils.copyProperties(commentVo, comment);

        // 获取用户id
        Map<String, Object> userData = UserThreadLocal.get();
        User user = (User) userData.get("user");
        //评论者id
        comment.setAuthorId(user.getId());

        // 如果评论有图片就上传图片到阿里云
        if (!ObjectUtils.isEmpty(commentVo.getImageBase64())) {
            MultipartFile multipartFile;
            try {
                multipartFile = Base64DecodeMultipartFileUtils.base64Convert(commentVo.getImageBase64());
            } catch (Exception e) {
                e.printStackTrace();
                return ResultVo.fail(400, "图片格式错误！");
            }
            String commentImagePath = fileLocalStorageTool.uploadImage("commentImages", 1, multipartFile);
            comment.setImageUrl(commentImagePath);
        }

        sbbCommentMapper.insert(comment);

        return ResultVo.success(comment.getId().toString());
    }

    /**
     * 删除评论
     *
     * @param commentId 评论id
     * @return
     */
    public ResultVo deleteComment(Long commentId) {
        VideoComment comment = sbbCommentMapper.selectById(commentId);
        if (!ObjectUtils.isEmpty(comment)) {
            Map<String, Object> userData = UserThreadLocal.get();
            User user = (User) userData.get("user");
            if (!user.getId().equals(comment.getAuthorId())) {
                return ResultVo.fail("没有操作权限");
            }
            sbbCommentMapper.deleteById(comment);
            return ResultVo.success("删除成功");
        } else {
            return ResultVo.fail("评论不存在");
        }

    }

    /**
     * 点赞评论
     *
     * @param commentLikeVo 评论内容
     * @param type          true：点赞  false：取消点赞
     * @return
     */
    public ResultVo likeComment(VideoCommentLike commentLikeVo, Boolean type) {
        VideoComment comment = sbbCommentLikeDao.getReplyLikeNum(commentLikeVo.getCommentId());

        if (ObjectUtils.isEmpty(comment)) {
            return ResultVo.fail("评论不存在");
        }

        // 获取用户id
        Map<String, Object> userData = UserThreadLocal.get();
        User user = (User) userData.get("user");
        commentLikeVo.setUserId(user.getId());

        //是否点赞
        Integer likeReply = sbbCommentLikeDao.isLikeReply(commentLikeVo.getCommentId(), user.getId());

        // 点赞
        if (type) {
            if(likeReply > 0){
                return ResultVo.fail("你已点赞");
            }
            comment.setLikeCount(comment.getLikeCount() + 1);
            sbbCommentLikeDao.insert(commentLikeVo);
        } else {
            if(likeReply <= 0){
                return ResultVo.fail("你未点赞");
            }
            // 取消点赞
            comment.setLikeCount(comment.getLikeCount() - 1);
            LambdaQueryWrapper<VideoCommentLike> commentLike = new LambdaQueryWrapper<>();
            commentLike.eq(VideoCommentLike::getCommentId, commentLikeVo.getCommentId())
                    .eq(VideoCommentLike::getUserId, commentLikeVo.getUserId());
            sbbCommentLikeDao.delete(commentLike);
        }

        sbbCommentMapper.updateById(comment);
        return ResultVo.success("true");
    }

    /**
     * 查询评论
     *
     * @param postsId 帖子id
     * @return
     */
    public ResultVo queryCommentV2(Long postsId) {
        //查询帖子的所有一级评论
        List<CommentDto> commentDtos = sbbCommentMapper.queryReplyByVideoId(postsId, 0, null);

        //获取所有评论（三级状态）
        recursiveCommonReplyList(postsId, commentDtos);

        //合并三级为二级
        mergeChildrenList(commentDtos);

        //获取其他数据
        getOrderInfo(commentDtos);

        return ResultVo.success(commentDtos).put("count", sbbCommentMapper.queryCommentsByVideoIdCount(postsId));
    }

    public void getOrderInfo(List<CommentDto> commentDtos){
        //获取当前查看评论的用户id
        Map<String, Object> userData = UserThreadLocal.get();
        Long userId;
        if(!ObjectUtils.isEmpty(userData)){
            User user = (User) userData.get("user");
            userId = !ObjectUtils.isEmpty(user) ? user.getId() : null;
        } else {
            userId = null;
        }

        //获取用户是否点赞
        commentDtos.stream().forEach(item -> {
            //二级
            item.getChildComments().forEach(childItem -> {
                if(!ObjectUtils.isEmpty(userId)){
                    //是否点赞
                    childItem.setIsLike(sbbCommentLikeDao.isLikeReply(item.getId(), userId) > 0);
                }else {
                    childItem.setIsLike(false);
                }
                if(LevenParam.TORHILD_LEVEN.equals(childItem.getLevel())){
                    childItem.setToAuthorName(userMapper.selectUserName(childItem.getToAuthorId()));
                }
                //头像域名
                childItem.setAuthorAvatar(ImageUtils.convertImageUrl(item.getAuthorAvatar()));
            });
            if(!ObjectUtils.isEmpty(userId)){
                //是否点赞
                item.setIsLike(sbbCommentLikeDao.isLikeReply(item.getId(), userId) > 0);
            }else {
                item.setIsLike(false);
            }
            //头像域名
            item.setAuthorAvatar(ImageUtils.convertImageUrl(item.getAuthorAvatar()));
        });
    }

    /**
     * 递归获取所有评论（层级关系状态）
     *
     * @param postId
     * @param courseCommonList
     */
    public void recursiveCommonReplyList(Long postId, List<CommentDto> courseCommonList) {
        for (CommentDto cd : courseCommonList) {
            List<CommentDto> courseCommonReplyList = sbbCommentMapper.queryReplyByVideoId(postId, 2, cd.getId());
            if (courseCommonReplyList != null) {
                cd.setChildComments(courseCommonReplyList);
                recursiveCommonReplyList(postId, courseCommonReplyList);
            }
        }
    }

    /**
     * 合并三级二级
     *
     * @param courseCommonList
     */
    public void mergeChildrenList(List<CommentDto> courseCommonList) {
        for (CommentDto comment : courseCommonList) {
            ArrayList<CommentDto> fatherChildren = new ArrayList<>();
            findChildren(comment, fatherChildren);
            comment.setChildComments(fatherChildren);
        }
    }

    /**
     * 合并
     *
     * @param parent
     * @param fatherChildren
     */
    public void findChildren(CommentDto parent, List<CommentDto> fatherChildren) {
        //找出直接⼦级
        List<CommentDto> comments = parent.getChildComments();
        //遍历直接⼦级的⼦级
        for (CommentDto comment : comments) {
            //若⾮空，则还有⼦级，递归
            if (!comment.getChildComments().isEmpty()) {
                findChildren(comment, fatherChildren);
            }
            //已经到了最底层的嵌套关系，将该回复放⼊新建⽴的集合
            fatherChildren.add(comment);
            //容易忽略的地⽅：将相对底层的⼦级放⼊新建⽴的集合之后
            //则表⽰解除了嵌套关系，对应的其⽗级的⼦级应该设为空
            comment.setChildComments(new ArrayList<>());
        }
    }

}
